package cgl.narada.transport.rtp;
/**
 * Software License, Version 1.0
 *
 * Copyright 2003 The Trustees of Indiana University.  All rights reserved.
 *
 *Redistribution and use in source and binary forms, with or without
 *modification, are permitted provided that the following conditions are met:
 *
 *1) All redistributions of source code must retain the above copyright notice,
 * the list of authors in the original source code, this list of conditions and
 * the disclaimer listed in this license;
 *2) All redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the disclaimer listed in this license in
 * the documentation and/or other materials provided with the distribution;
 *3) Any documentation included with all redistributions must include the
 * following acknowledgement:
 *
 *"This product includes software developed by the Community Grids Lab. For
 * further information contact the Community Grids Lab at
 * http://communitygrids.iu.edu/."
 *
 * Alternatively, this acknowledgement may appear in the software itself, and
 * wherever such third-party acknowledgments normally appear.
 *
 *4) The name Indiana University or Community Grids Lab or GlobalMMCS,
 * shall not be used to endorse or promote products derived from this software
 * without prior written permission from Indiana University.  For written
 * permission, please contact the Advanced Research and Technology Institute
 * ("ARTI") at 351 West 10th Street, Indianapolis, Indiana 46202.
 *5) Products derived from this software may not be called GlobalMMCS,
 * nor may Indiana University or Community Grids Lab or GlobalMMCS appear
 * in their name, without prior written permission of ARTI.
 *
 * Indiana University provides no reassurances that the source code provided
 * does not infringe the patent or any other intellectual property rights of
 * any other entity.  Indiana University disclaims any liability to any
 * recipient for claims brought by any other entity based on infringement of
 * intellectual property rights or otherwise.
 *
 *LICENSEE UNDERSTANDS THAT SOFTWARE IS PROVIDED "AS IS" FOR WHICH NO
 *WARRANTIES AS TO CAPABILITIES OR ACCURACY ARE MADE. INDIANA UNIVERSITY GIVES
 *NO WARRANTIES AND MAKES NO REPRESENTATION THAT SOFTWARE IS FREE OF
 *INFRINGEMENT OF THIRD PARTY PATENT, COPYRIGHT, OR OTHER PROPRIETARY RIGHTS.
 *INDIANA UNIVERSITY MAKES NO WARRANTIES THAT SOFTWARE IS FREE FROM "BUGS",
 *"VIRUSES", "TROJAN HORSES", "TRAP DOORS", "WORMS", OR OTHER HARMFUL CODE.
 *LICENSEE ASSUMES THE ENTIRE RISK AS TO THE PERFORMANCE OF SOFTWARE AND/OR
 *ASSOCIATED MATERIALS, AND TO THE PERFORMANCE AND VALIDITY OF INFORMATION
 *GENERATED USING SOFTWARE.
 */


/**
 * This class is used to set the freeze release bit of a H.261 package
 *
 * @author Ahmet Uyar
 * @version 1.0
 */

public class H261BitSetter {

   public static final byte H261_PAYLOAD_TYPE = 31;

   public H261BitSetter() {
   }

   /**
    * if this package is an H.261 package and  if the package is a picture start package
    * @param data data array
    * @param offset the start of data in the array
    * @param length the length of the data in the array
    */
   public void setBit(byte data[], int offset, int length){

      if(isFormatH261(data, offset, length) && isPictureStart(data, offset, length)){
         setFreezeReleaseBit(data, offset, length);
      }
   }

   /**
    * if this package is the start of a H.261 picture start
    * then return true, otherwise false;
    */
   private boolean isPictureStart(byte data[], int offset, int length){
      if(length < 20)
         return false;

      // if bytes starting from 17th has the data
      // 00000000 00000001 0000XXXX, this means
      // byte 17th must be zero
      // byte 18th must be 1
      // byte 19th must be less than 16

      if(data[offset+16] == 0  &&  data[offset+17] == 1  &&  data[offset+18] < 16){
         return true;
      }
      return false;
   }

   /**
    * if it can set the freeze release bit to 1
    * then return true, otherwise false;
    */
   private boolean setFreezeReleaseBit(byte data[], int offset, int length){
      if(length < 20)
         return false;

      // we will set the 4th most significant bit of 20th byte to 1
      byte sixteen = (byte)( 1 << 4); // 00010000
      byte four    = (byte)( 1 << 2); // 00000100
//      data[offset + 19] = (byte)(data[offset + 19] | sixteen);
      data[offset + 19] = (byte)(data[offset + 19] | sixteen | four);
      return true;
   }


   /**
    * if the payload type of this rtp package is H261
    * return true, otherwise false
    */
   private boolean isFormatH261(byte data[], int offset, int length){
      if( getPayloadType(data, offset, length) == H261_PAYLOAD_TYPE){
         return true;
      }

      return false;
   }

   /**
    * return the payload type of an rtp package
    */
   private byte getPayloadType(byte data[], int offset, int length){
      // get the payload type from rtp header
      // payload type is 7 bits. They are the bits from 10th to 16th inclusive

      byte secondByte = data[offset + 1];
      // set the most significant bit of secondByte off
      byte oneHundredTwentySeven =  127; // 01111111
      secondByte = (byte)(oneHundredTwentySeven & secondByte);
      return secondByte;
   }
}
